<template>
  <div class="app-container">
    <el-card>
      <div slot="header" class="clearfix">
        <span>部门树可视化管理</span>
        <div style="float: right;">
          <el-button
            type="text"
            icon="el-icon-download"
            @click="exportImage"
            style="margin-right: 10px;"
          >导出图片</el-button>
          <el-button
            type="text"
            icon="el-icon-plus"
            @click="handleAdd"
          >新增</el-button>
        </div>
      </div>

      <div class="org-tree-container" v-loading="loading" ref="orgChart">
        <organization-chart
          v-if="processedData"
          :datasource="processedData"
          :pan="true"
          :zoom="true"
          @node-add="handleAddChild"
          @node-update="handleUpdate"
          @node-delete="handleDelete"
        />
      </div>
    </el-card>

    <!-- 添加或修改部门对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="部门类型" prop="deptType">
          <el-select 
            v-model="form.deptType" 
            placeholder="请选择部门类型"
            @change="handleDeptTypeChange"
          >
            <el-option
              v-for="item in deptTypeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="上级部门" prop="parentId" v-if="form.deptType !== 0">
          <el-select 
            v-model="form.parentId"
            placeholder="请选择上级部门"
            filterable
          >
            <el-option
              v-for="item in parentDeptOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="部门名称" prop="deptName">
          <el-input v-model="form.deptName" placeholder="请输入部门名称" />
        </el-form-item>
        <el-form-item label="显示排序" prop="orderNum">
          <el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
        </el-form-item>
        <el-form-item label="部门状态" prop="status">
          <el-radio-group v-model="form.status">
            <el-radio :label="1">正常</el-radio>
            <el-radio :label="0">停用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import request from '@/utils/request'
import OrganizationChart from '@/components/OrganizationChart/Container.vue'
import html2canvas from 'html2canvas'

export default {
  name: 'DepartmentView',
  components: {
    OrganizationChart
  },
  data() {
    return {
      loading: true,
      deptData: [],
      processedData: null,
      defaultProps: {
        children: 'children',
        label: 'deptName'
      },
      form: {
        deptId: undefined,
        parentId: undefined,
        deptName: undefined,
        deptType: undefined,
        orderNum: 0,
        status: 1
      },
      title: '',
      open: false,
      rules: {
        parentId: [
          { required: true, message: '上级部门不能为空', trigger: 'blur' }
        ],
        deptName: [
          { required: true, message: '部门名称不能为空', trigger: 'blur' }
        ],
        deptType: [
          { required: true, message: '部门类型不能为空', trigger: 'blur' }
        ],
        orderNum: [
          { required: true, message: '显示排序不能为空', trigger: 'blur' }
        ]
      },
      hasOrderChanged: false,
      orderChangeMap: new Map(),
      deptTypeOptions: [
        { label: '合作社总部', value: 0 },
        { label: '烟站', value: 1 },
        { label: '乡镇', value: 2 },
        { label: '乡村组', value: 3 },
        { label: '育苗点', value: 4 },
        { label: '仓库', value: 5 }
      ],
      parentDeptOptions: []
    }
  },
  computed: {
    deptOptions() {
      const options = []
      const flatten = (list) => {
        list.forEach(item => {
          if (this.form.deptId !== item.deptId) {
            let canSelect = true
            if (this.form.deptType !== undefined) {
              switch (this.form.deptType) {
                case 0:
                  canSelect = false
                  break
                case 1:
                  canSelect = item.deptType === 0
                  break
                case 2:
                  canSelect = item.deptType === 1
                  break
                case 3:
                  canSelect = item.deptType === 2
                  break
                case 4:
                  canSelect = item.deptType === 0
                  break
                case 5:
                  canSelect = item.deptType === 0
                  break
              }
            }
            if (canSelect) {
              options.push({
                deptId: item.deptId,
                deptName: item.deptName,
                deptType: item.deptType
              })
            }
          }
          if (item.children) {
            flatten(item.children)
          }
        })
      }
      flatten(this.deptData)
      return options
    }
  },
  created() {
    this.getDeptData()
  },
  methods: {
    processTreeData(data) {
      if (!data || data.length === 0) return null
      const root = data[0]
      return this.transformNode(root)
    },
    transformNode(node) {
      const result = {
        id: node.deptId,
        name: node.deptName,
        status: node.status,
        deptType: node.deptType,
        deptId: node.deptId,
        orderNum: node.orderNum,
        children: []
      }
      
      if (node.children && node.children.length > 0) {
        result.children = node.children
          .sort((a, b) => a.orderNum - b.orderNum)
          .map(child => this.transformNode(child))
      }
      
      return result
    },
    getDeptData() {
      this.loading = true
      request({
        url: '/departments/tree',
        method: 'get'
      }).then(response => {
        this.deptData = response
        this.processedData = this.processTreeData(response)
        this.loading = false
      })
    },
    getNodeClass(data) {
      const typeClasses = {
        0: 'node-headquarter',
        1: 'node-station',
        2: 'node-town',
        3: 'node-village',
        4: 'node-nursery',
        5: 'node-warehouse'
      }
      return typeClasses[data.deptType] || ''
    },
    handleUpdate(row) {
      this.reset()
      const deptId = row.deptId || row.id
      if (!deptId) {
        this.$message.error('获取部门ID失败')
        return
      }
      request({
        url: '/departments/' + deptId,
        method: 'get'
      }).then(response => {
        this.form = response
        this.open = true
        this.title = '修改部门'
      }).catch(error => {
        console.error('获取部门信息失败:', error)
        this.$message.error('获取部门信息失败')
      })
    },
    submitForm() {
      this.$refs['form'].validate(valid => {
        if (valid) {
          if (this.form.deptId !== undefined) {
            request({
              url: '/departments',
              method: 'put',
              data: this.form
            }).then(() => {
              this.$message.success('修改成功')
              this.open = false
              this.getDeptData()
            })
          } else {
            request({
              url: '/departments',
              method: 'post',
              data: this.form
            }).then(() => {
              this.$message.success('新增成功')
              this.open = false
              this.getDeptData()
            })
          }
        }
      })
    },
    handleDelete(row) {
      request({
        url: '/departments/check-delete/' + row.deptId,
        method: 'get'
      }).then(response => {
        const { canDelete, message, childDepts } = response
        if (canDelete) {
          let warningMessage = '确认要删除该部门吗？'
          if (childDepts && childDepts.length > 0) {
            warningMessage = `该部门下有${childDepts.length}个子部门，删除后将同时删除所有子部门，是否继续？`
          }
          this.$confirm(warningMessage, '警告', {
            type: 'warning'
          }).then(() => {
            return request({
              url: '/departments/' + row.deptId,
              method: 'delete'
            })
          }).then(() => {
            this.$message.success('删除成功')
            this.getDeptData()
          }).catch(err => {
            if (err !== 'cancel') {
              console.error('删除失败:', err)
              this.$message.error('删除失败')
            }
          })
        } else {
          this.$message.warning(message)
        }
      }).catch(err => {
        console.error('检查删除条件失败:', err)
        this.$message.error('检查删除条件失败')
      })
    },
    reset() {
      this.form = {
        deptId: undefined,
        parentId: undefined,
        deptName: undefined,
        deptType: undefined,
        orderNum: 0,
        status: 1
      }
      this.$nextTick(() => {
        this.$refs['form']?.resetFields()
      })
    },
    cancel() {
      this.open = false
      this.reset()
      return Promise.resolve()
    },
    // 监听部门类型变化
    async handleDeptTypeChange() {
      // 清空上级部门的选择
      this.form.parentId = undefined
      // 重新获取可选的上级部门
      const options = await this.getParentDeptOptions()
      // 更新上级部门选项
      this.parentDeptOptions = options
    },
    labelClassName(data) {
      return this.getNodeClass(data)
    },
    renderContent(h, data) {
      return h('div', {
        class: {
          'custom-org-node': true,
          [this.getNodeClass(data)]: true
        },
        style: {
          cursor: 'pointer'
        }
      }, [
        h('div', {
          class: 'title'
        }, data.label),
        h('div', {
          class: 'status'
        }, [
          h('el-tag', {
            props: {
              size: 'mini',
              type: data.status === 1 ? 'success' : 'info'
            }
          }, data.status === 1 ? '正常' : '停用')
        ]),
        h('div', {
          class: 'operations'
        }, [
          h('el-button', {
            props: {
              type: 'text',
              size: 'mini'
            },
            on: {
              click: (e) => {
                e.stopPropagation()
                this.handleUpdate(data)
              }
            }
          }, '修改'),
          h('el-button', {
            props: {
              type: 'text',
              size: 'mini'
            },
            on: {
              click: (e) => {
                e.stopPropagation()
                this.handleDelete(data)
              }
            }
          }, '删除')
        ])
      ])
    },
    handleAdd() {
      this.reset()
      this.open = true
      this.title = '新增部门'
    },
    handleAddChild(node) {
      this.reset()
      // 设置父部门ID
      this.form.parentId = node.deptId
      
      // 根据父部门类型设置子部门类型
      switch (node.deptType) {
        case 0: // 总部
          this.form.deptType = undefined // 可以选择育苗点(4)或烟站(1)
          break
        case 1: // 烟站
          this.form.deptType = 2 // 只能是乡镇
          break
        case 2: // 乡镇
          this.form.deptType = 3 // 只能是乡村组
          break
        case 3: // 乡村组
        case 4: // 育苗点
          this.$message.warning('该部门类型不能添加子部门')
          return
      }
      
      this.open = true
      this.title = '新增子部门'
    },
    async exportImage() {
      try {
        this.$message({
          message: '正在生成图片，请稍候...',
          type: 'info'
        })
        
        // 等待下一个渲染周期，确保DOM已更新
        await this.$nextTick()
        
        const element = this.$refs.orgChart
        
        // 保存原始样式
        const originalStyle = {
          height: element.style.height,
          overflow: element.style.overflow,
          position: element.style.position,
          transform: element.querySelector('.orgchart').style.transform
        }
        
        // 临时修改样式以确保完整捕获
        element.style.height = 'auto'
        element.style.overflow = 'visible'
        element.style.position = 'relative'
        element.querySelector('.orgchart').style.transform = 'none'
        
        // 获取实际内容大小
        const contentRect = element.querySelector('.orgchart').getBoundingClientRect()
        
        // 设置临时容器大小
        element.style.width = contentRect.width + 'px'
        element.style.height = contentRect.height + 'px'
        
        const canvas = await html2canvas(element, {
          backgroundColor: '#f0f2f5',
          scale: 2, // 提高清晰度
          useCORS: true, // 允许加载跨域图片
          logging: false, // 关闭日志
          width: contentRect.width,
          height: contentRect.height,
          scrollX: 0,
          scrollY: 0,
          windowWidth: contentRect.width,
          windowHeight: contentRect.height
        })
        
        // 恢复原始样式
        element.style.height = originalStyle.height
        element.style.overflow = originalStyle.overflow
        element.style.position = originalStyle.position
        element.querySelector('.orgchart').style.transform = originalStyle.transform
        
        // 创建下载链接
        const link = document.createElement('a')
        link.download = '部门组织架构图_' + new Date().getTime() + '.png'
        link.href = canvas.toDataURL('image/png')
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        
        this.$message({
          message: '导出成功',
          type: 'success'
        })
      } catch (error) {
        console.error('导出图片失败:', error)
        this.$message.error('导出图片失败，请重试')
      }
    },
    // 获取可选的部门类型
    getDeptTypeOptions(parentType) {
      const options = [
        { label: '总部', value: 0 },
        { label: '烟站', value: 1 },
        { label: '乡镇', value: 2 },
        { label: '乡村组', value: 3 },
        { label: '育苗点', value: 4 },
        { label: '仓库', value: 5 }
      ]

      // 如果是仓库类型，允许选择任意类型作为父部门
      if (this.form.deptType === 5) {
        return options
      }

      // 根据父部门类型过滤可选的子部门类型
      switch (parentType) {
        case 0: // 总部的子部门可以是烟站、育苗点或仓库
          return options.filter(opt => [1, 4, 5].includes(opt.value))
        case 1: // 烟站的子部门可以是乡镇或仓库
          return options.filter(opt => [2, 5].includes(opt.value))
        case 2: // 乡镇的子部门可以是乡村组或仓库
          return options.filter(opt => [3, 5].includes(opt.value))
        case 3: // 乡村组的子部门可以是仓库
          return options.filter(opt => [5].includes(opt.value))
        case 4: // 育苗点不能有子部门
          return []
        case 5: // 仓库不能有子部门
          return []
        default:
          return options
      }
    },
    // 获取可选的上级部门
    async getParentDeptOptions() {
      try {
        const response = await request.get('/departments/tree')
        // 如果是仓库类型，允许选择任意部门作为上级部门（除了育苗点和仓库）
        if (this.form.deptType === 5) {
          return this.flattenDeptTree(response)
        }
        // 否则按照原有逻辑过滤
        return this.filterParentDepts(response)
      } catch (error) {
        console.error('获取部门树失败:', error)
        this.$message.error('获取部门树失败')
        return []
      }
    },
    // 过滤父部门选项
    filterParentDepts(tree) {
      const result = []
      const flatten = (nodes) => {
        nodes.forEach(node => {
          let canBeParent = false
          switch (this.form.deptType) {
            case 0: // 总部不需要父部门
              break
            case 1: // 烟站的父部门只能是总部
              canBeParent = node.deptType === 0
              break
            case 2: // 乡镇的父部门只能是烟站
              canBeParent = node.deptType === 1
              break
            case 3: // 乡村组的父部门只能是乡镇
              canBeParent = node.deptType === 2
              break
            case 4: // 育苗点的父部门可以是总部
              canBeParent = node.deptType === 0
              break
            case 5: // 仓库可以挂在任何部门下（除了育苗点和仓库）
              canBeParent = node.deptType !== 4 && node.deptType !== 5
              break
          }
          if (canBeParent) {
            result.push({
              value: node.deptId,
              label: node.deptName
            })
          }
          if (node.children && node.children.length > 0) {
            flatten(node.children)
          }
        })
      }
      flatten(tree)
      return result
    },
    // 扁平化部门树
    flattenDeptTree(tree) {
      const result = []
      const flatten = (nodes) => {
        nodes.forEach(node => {
          // 排除育苗点和仓库作为父部门
          if (node.deptType !== 4 && node.deptType !== 5) {
            result.push({
              value: node.deptId,
              label: node.deptName
            })
          }
          if (node.children && node.children.length > 0) {
            flatten(node.children)
          }
        })
      }
      flatten(tree)
      return result
    }
  }
}
</script>

<style lang="scss" scoped>
.app-container {
  padding: 20px;
}

.org-tree-container {
  margin: 20px 0;
  padding: 20px;
  background-color: #fff;
  min-height: 800px;
  overflow: auto;
  
  // 确保导出时内容完整
  &.exporting {
    overflow: visible;
    height: auto;
  }

  :deep(.node-headquarter) {
    background-color: #409EFF !important;
    color: white !important;
  }

  :deep(.node-station) {
    background-color: #67C23A !important;
    color: white !important;
  }

  :deep(.node-town) {
    background-color: #E6A23C !important;
    color: white !important;
  }

  :deep(.node-village) {
    background-color: #F56C6C !important;
    color: white !important;
  }

  :deep(.node-nursery) {
    background-color: #909399 !important;
    color: white !important;
  }

  :deep(.node-warehouse) {
    background-color: #8E44AD !important;
    color: white !important;
  }
}

.custom-node {
  &:hover {
    .node-operations {
      display: flex !important;
      gap: 8px;
      justify-content: center;
    }
  }
}

:deep(.tree-chart) {
  width: 100%;
  min-height: 800px;
}

:deep(.el-tag--mini) {
  height: 22px;
  padding: 0 8px;
  line-height: 20px;
  font-size: 12px;
}

:deep(.el-button--mini) {
  padding: 5px 10px;
  font-size: 12px;
}
</style> 